package com.java.cg.order.listener;

import com.java.cg.order.service.OrderService;
import com.java.common.constants.MQConstants;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

/**
 * @author jiangli
 * @since 2020/2/20 10:21
 */
@Component
@Slf4j
public class OrderConsumer {
	@Autowired
	private OrderService orderService;

	/**
	 * 监听订单支付回调中的消息然后修改订单状态
	 */
	@RabbitListener(bindings = @QueueBinding(
			value = @Queue(value = "cg.order.pay.queue", durable = "true"),
			exchange = @Exchange(
					value = MQConstants.ORDER_EXCHANGE,
					ignoreDeclarationExceptions = "true",
					type = ExchangeTypes.TOPIC),
			key = {MQConstants.PAY_SUCCESS_ROUTING_KEY}
	))
	public void updateOrderStatus(Map<String, String> msg) {
		//通信标识 return_code  //业务结果 result_code
		String return_code = msg.get("return_code");
		if ("SUCCESS".equals(return_code) && "SUCCESS".equals(msg.get("result_code"))) {
			//微信支付交易流水号 transaction_id
			String transaction_id = msg.get("transaction_id");
			//订单号 out_trade_no
			String out_trade_no = msg.get("out_trade_no");
			//支付完成时间
			String time_end = msg.get("time_end");
			orderService.updateOrderStatus(out_trade_no,transaction_id,time_end);
		}
	}

	/**
	 * 监听死信队列,定时关单
	 */
	@RabbitListener(queues = {"ORDER-CLOSE-QUEUE"})
	public void closeOrder(String orderToken, Channel channel, Message message) {
		try {
			// 关单
			if (orderService.closeOrder(orderToken) == 1) {
				// 如果关单成功，发送消息给库存系统，释放库存
//				this.amqpTemplate.convertAndSend("gmall-cart-exchange", "cart.unlock", orderToken);
			}
			// 如果关单失败，说明订单可能已被关闭，直接确认消息
			// 手动ACK
			channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
		} catch (IOException e) {
			// 消费失败后重新入队
			try {
				channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
			} catch (IOException e1) {
				log.error("释放库存失败,orderToken=[{}]", orderToken);
			}
		}
	}
}
